﻿using System;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using GraphSharp.Controls;
using XmlStudio.Helper;
using System.Windows;

namespace XmlStudio.Controls {
    /// <summary>
    /// Represents the object which causes other objects to be draggable.
    /// </summary>
    public class DragThumb : Thumb {
        #region Constructors
        /// <summary>
        /// Initializes a new instance of the DragThumb class.
        /// </summary>
        public DragThumb() {
            // add new event handler for the DragDelta event
            DragDelta += DragThumb_DragDelta;
        }
        #endregion

        #region Methods
        public void UpdateOrder() {
            //DesignerItem designerItem = this.DataContext as DesignerItem; // reference to the item on the canvas
            //DesignerCanvas canvas = VisualTreeHelper.GetParent(designerItem) as DesignerCanvas; // reference to the canvas

            //if(designerItem != null && canvas != null && designerItem.IsSelected) {
            //    // select all selected DesignerItems
            //    var designerItems = canvas.selectionService.CurrentSelection.OfType<DesignerItem>();

            //    foreach(DesignerItem item in designerItems) {
            //        Connector topConnector = item.GetConnector(Connectors.Top); // get the top Connector of the DesignerItem
            //        if(topConnector.Connections.Count > 1) {
            //            throw new Exception("Child has more than one param!");
            //        } else if(topConnector.Connections.Count == 1) { // find its param
            //            Connection con = topConnector.Connections[0];
            //            DesignerItem param = con.Source.ParentDesignerItem;

            //            Connector bottomConnector = param.GetConnector(Connectors.Bottom); // get param's bottom connector

            //            List<DesignerItem> children = new List<DesignerItem>(); // get param's child nodes
            //            foreach(Connection c in bottomConnector.Connections) {
            //                children.Add(c.Sink.ParentDesignerItem);
            //            }

            //            // get Order numbers, sort them
            //            var orders = (from child in children select child.Info.Order).OrderBy(order => order);

            //            // sort them according to their position
            //            children.Sort((Comparison<DesignerItem>)((DesignerItem item1, DesignerItem item2) => {
            //                if(Canvas.GetLeft(item1) < Canvas.GetLeft(item2))
            //                    return -1;
            //                else if(Canvas.GetLeft(item1) == Canvas.GetLeft(item2))
            //                    return 0;
            //                else
            //                    return 1;
            //            }));

            //            // assign Order numbers to DesignerItems
            //            for(int i = 0; i < orders.Count(); ++i) {
            //                children[i].Info.Order = orders.ElementAt(i);
            //            }

            //            // get neccessary items for controller so it can update xmlModel
            //            XElement parentElement = param.Element;
            //            List<XNode> childNodes = new List<XNode>();
            //            foreach(DesignerItem i in children) {
            //                childNodes.Add(i.Node);
            //            }

            //            Document.CurrentController.UpdateOrder(parentElement, childNodes);
            //        }
            //    }
            //    canvas.InvalidateMeasure();
            //}
        }
        #endregion

        #region Event handlers
        protected override void OnMouseUp(System.Windows.Input.MouseButtonEventArgs e) {
            base.OnMouseUp(e);

            //UpdateOrder();

            e.Handled = true;
        }

        /// <summary>
        /// DragDeltaEvent handler.
        /// </summary>
        /// <param name="sender">The object where the event handler is attached.</param>
        /// <param name="e">The event data.</param>
        void DragThumb_DragDelta(object sender, DragDeltaEventArgs e) {
            var designerItem = this.DataContext as VertexControl; // reference to the item on the canvas

            if(designerItem != null && designerItem.IsSelected) {
                double minLeft = double.MaxValue;
                double minTop = double.MaxValue;

                // we only move DesignerItems
                var designerItems = SelectionService.GetCurrentInstance(sender as DependencyObject).CurrentSelection.OfType<VertexControl>();
                var canvas = VisualTreeHelper.GetParent(designerItem) as GraphCanvas; // reference to the canvas

                foreach(var item in designerItems) {
                    double left = Canvas.GetLeft(item);
                    double top = Canvas.GetTop(item);

                    minLeft = double.IsNaN(left) ? 0 : Math.Min(left, minLeft);
                    minTop = double.IsNaN(top) ? 0 : Math.Min(top, minTop);
                }

                double deltaHorizontal = Math.Max(-minLeft, e.HorizontalChange);
                double deltaVertical = Math.Max(-minTop, e.VerticalChange);

                foreach(var item in designerItems) {
                    double left = Canvas.GetLeft(item);
                    double top = Canvas.GetTop(item);

                    if(double.IsNaN(left))
                        left = 0;
                    if(double.IsNaN(top))
                        top = 0;

                    Canvas.SetLeft(item, left + deltaHorizontal);
                    Canvas.SetTop(item, top + deltaVertical);
                }

                if(canvas != null)
                    canvas.InvalidateMeasure();
                e.Handled = true;
            }
        }
        #endregion
    }
}
